package com.myk.game.gobangchess.rooms.absrooms;

import com.myk.game.gobangchess.*;
import com.myk.game.gobangchess.constants.ColorCost;
import com.myk.game.gobangchess.constants.Msger;
import com.myk.game.gobangchess.signs.GroundSign;
import com.myk.game.gobangchess.utils.GridsUtils;
import com.myk.game.gobangchess.utils.SignsUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

/**
 * 同时制棋的抽象类
 */
public abstract class AbsSameTimeRoom extends Room {

    protected int[] blackPrePoint = null; //黑棋预落点，赋值时必定赋长度为3的数组，分别是row，col和value
    protected int[] whitePrePoint = null; //白棋预落点

    public AbsSameTimeRoom(String roomName, String roomIntroduce, String chessName, int[][] curGrids, boolean isSupportPersonal, boolean isSaveHistoryToFile,String ... modes) {
        super(roomName, roomIntroduce, chessName, curGrids, isSupportPersonal, isSaveHistoryToFile,modes);
    }

    @Override
    protected void onStartPrepare() {
        noticeAllMove();
    }

    @Override
    public void resetGrids() {
        super.resetGrids();
        cur = 0;
        blackPrePoint = null;
        whitePrePoint = null;
    }

    @Override
    public void moveLater(Player player, int row, int col) {
        if (curGrids[row][col] != 0) {
            return; //默认只能落在空格
        }
        if (cur == 1) { //白棋已经落下仅黑棋可落
            if (player_black == player) {
                blackPrePoint = new int[]{row, col, 1};
                checkMovedState();
            }
        }
        else if (cur == 2) { //黑棋已经落下仅白棋可落
            if (player_white == player) {
                whitePrePoint = new int[]{row, col, 2};
                checkMovedState();
            }
        }
        else if (cur == 3) { //双方都可以落下
            blackPrePoint = null;
            whitePrePoint = null;
            if (player_black == player) {
                blackPrePoint = new int[]{row, col, 1};
                noticeWhiteMove();
            }
            else if (player_white == player) {
                whitePrePoint = new int[]{row, col, 2};
                noticeBlackMove();
            }
        }
        else {

        }
    }

    @Override
    public void doRule(int row, int col, int value) {

    }

    @Override
    protected void noticeAllRefreshGameInfo() {
        if (player_black != null) {
            player_black.sendMessage(Msger.refreshGameInfo, getBlackGameInfo());
        }
        if (player_white != null) {
            player_white.sendMessage(Msger.refreshGameInfo, getWhiteGameInfo());
        }
        if (spectatorList.size() > 0) {
            String gameInfo = getGameInfo();
            for (Player player : spectatorList) {
                if (player!=null){
                    player.sendMessage(Msger.refreshGameInfo, gameInfo);
                }
            }
        }
    }

    @Override
    public String getGameInfo() {
        List<Sign> selfSigns = new ArrayList<>();
        if (blackPrePoint != null && whitePrePoint != null) {
            selfSigns.add(new GroundSign(getIndex(blackPrePoint[0], blackPrePoint[1]), "#00000000", ColorCost.NEW_PUT_POINT, 1f, 0, 0));
            selfSigns.add(new GroundSign(getIndex(whitePrePoint[0], whitePrePoint[1]), "#00000000", ColorCost.NEW_PUT_POINT, 1f, 0, 0));
        }
        return "" + step +
                "&" + cur +
                "&" + blackScore +
                "&" + whiteScore +
                "&" + gameTip +
                "&" + GridsUtils.grids2Str(curGrids) +
                "&" + SignsUtils.signs2Str(selfSigns) +
                "&" + getCoordMode();
    }

    protected String getBlackGameInfo() {
        int[][] selfGrids = GridsUtils.copyGrids(curGrids);
        List<Sign> selfSigns = new ArrayList<>();
        if (blackPrePoint != null && whitePrePoint != null) {
            selfSigns.add(new GroundSign(getIndex(blackPrePoint[0], blackPrePoint[1]), "#00000000", ColorCost.NEW_PUT_POINT, 1f, 0, 0));
            selfSigns.add(new GroundSign(getIndex(whitePrePoint[0], whitePrePoint[1]), "#00000000", ColorCost.NEW_PUT_POINT, 1f, 0, 0));
        }
        else if (blackPrePoint != null) {
            selfSigns.add(new GroundSign(getIndex(blackPrePoint[0], blackPrePoint[1]), "#00000000", ColorCost.NEW_PUT_POINT, 1f, 0, 1));
            selfGrids[blackPrePoint[0]][blackPrePoint[1]] = blackPrePoint[2];
        }
        return "" + step +
                "&" + cur +
                "&" + blackScore +
                "&" + whiteScore +
                "&" + gameTip +
                "&" + GridsUtils.grids2Str(selfGrids) +
                "&" + SignsUtils.signs2Str(selfSigns)+
                "&" + getCoordMode();
    }

    protected String getWhiteGameInfo() {
        int[][] selfGrids = GridsUtils.copyGrids(curGrids);
        List<Sign> selfSigns = new ArrayList<>();
        if (blackPrePoint != null && whitePrePoint != null) {
            selfSigns.add(new GroundSign(getIndex(blackPrePoint[0], blackPrePoint[1]), "#00000000", ColorCost.NEW_PUT_POINT, 1f, 0, 0));
            selfSigns.add(new GroundSign(getIndex(whitePrePoint[0], whitePrePoint[1]), "#00000000", ColorCost.NEW_PUT_POINT, 1f, 0, 0));
        }
        else if (whitePrePoint != null) {
            selfSigns.add(new GroundSign(getIndex(whitePrePoint[0], whitePrePoint[1]), "#00000000", ColorCost.NEW_PUT_POINT, 1f, 0, 1));
            selfGrids[whitePrePoint[0]][whitePrePoint[1]] = whitePrePoint[2];
        }
        return "" + step +
                "&" + cur +
                "&" + blackScore +
                "&" + whiteScore +
                "&" + gameTip +
                "&" + GridsUtils.grids2Str(selfGrids) +
                "&" + SignsUtils.signs2Str(selfSigns) +
                "&" + getCoordMode();
    }

    /**
     * 检查移动后的状态
     */
    private void checkMovedState() {
        doSameTimeRule(blackPrePoint[0], blackPrePoint[1], blackPrePoint[2], whitePrePoint[0], whitePrePoint[1], whitePrePoint[2]);
        stepAdd();;
    }


    public abstract void doSameTimeRule(int blackRow, int blackCol, int blackValue, int whiteRow, int whiteCol, int whiteValue);

}
